package com.engine.salary.web;

import com.engine.common.util.ParamUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.salary.common.SalaryContext;
import com.engine.salary.entity.hrm.dto.HrmInfoDTO;
import com.engine.salary.entity.hrm.param.HrmQueryParam;
import com.engine.salary.entity.siaccount.dto.InsuranceAccountTabDTO;
import com.engine.salary.entity.siaccount.dto.InsuranceAccountViewListDTO;
import com.engine.salary.entity.siaccount.dto.InsuranceAcctDetailImportFieldDTO;
import com.engine.salary.entity.siaccount.dto.InsuranceCompensationDTO;
import com.engine.salary.entity.siaccount.param.*;
import com.engine.salary.entity.siaccount.po.InsuranceAccountBatchPO;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.service.SIAccountService;
import com.engine.salary.service.impl.SIAccountServiceImpl;
import com.engine.salary.util.ResponseResult;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.wrapper.SIAComparisonResultWrapper;
import com.engine.salary.wrapper.SIAccountWrapper;
import com.engine.salary.wrapper.SalaryFormulaWrapper;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 福利核算控制器
 */
@Slf4j
public class SIAccountController {

    public SIAccountService getService(User user) {
        SalaryContext.get().setValue("user",user);
        return ServiceUtil.getService(SIAccountServiceImpl.class, user);
    }

    public SIAccountWrapper getSIAccountWrapper(User user) {
        return ServiceUtil.getService(SIAccountWrapper.class,user);
    }

    private SalaryFormulaWrapper getSalaryFormulaWrapper(User user) {
        return (SalaryFormulaWrapper) ServiceUtil.getService(SalaryFormulaWrapper.class, user);
    }

    private SIAComparisonResultWrapper getSIAComparisonResultWrapper(User user) {
        return (SIAComparisonResultWrapper) ServiceUtil.getService(SIAComparisonResultWrapper.class, user);
    }

    /**
     * 获取台账列表页
     *
     * @param request
     * @param response
     * @return
     */
    @POST
    @Path("/batch/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String list(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAccountBatchParam insuranceAccountBatchParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountBatchParam, Map<String, Object>>(user).run(getService(user)::listPage, insuranceAccountBatchParam);
    }

    /**
     * 获取正常缴纳列表
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/common/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String commonList(@Context HttpServletRequest request, @Context HttpServletResponse response,
                             @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listCommonPage, insuranceAccountDetailParam);
    }


    /**
     * 获取正常缴纳列表合计行
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/common/list/sum")
    @Produces(MediaType.APPLICATION_JSON)
    public String commonListSum(@Context HttpServletRequest request, @Context HttpServletResponse response,
                             @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listCommonSum, insuranceAccountDetailParam);
    }


    /**
     * 根据姓名获取正常缴纳列表
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/common/search")
    @Produces(MediaType.APPLICATION_JSON)
    public String commonByNameList(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                   @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listCommonPageByName, insuranceAccountDetailParam);
    }

    /**
     * 获取补缴缴纳列表
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/supplementary/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String listSupplementaryPage(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                        @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listSupplementaryPage, insuranceAccountDetailParam);
    }

    /**
     * 获取补缴缴纳列表合计行
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/supplementary/list/sum")
    @Produces(MediaType.APPLICATION_JSON)
    public String listSupplementarySum(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                        @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listSupplementarySum, insuranceAccountDetailParam);
    }

    /**
     * 根据姓名获取补缴缴纳列表
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/supplementary/search")
    @Produces(MediaType.APPLICATION_JSON)
    public String supplementaryByNameList(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                          @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::supplementaryByNameList, insuranceAccountDetailParam);
    }


    /**
     * 获取核算月份备注填写表单
     *
     * @param request
     * @param response
     * @return
     */
    @GET
    @Path("/accountForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getBaseForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult< Map<String, Object>,  Map<String, Object>>(user).run(getService(user)::getForm, ParamUtil.request2Map(request));
    }


    /**
     * 保存并进入核算
     *
     * @param request
     * @param response
     * @param param
     * @return
     */
    @POST
    @Path("/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String save(@Context HttpServletRequest request, @Context HttpServletResponse response,
                       @RequestBody AccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AccountParam, String>(user).run(getService(user)::save, param);
    }


    /**
     * 正常缴纳页核算
     *
     * @param request
     * @param response
     * @param param
     * @return
     */
    @POST
    @Path("/commonAccount")
    @Produces(MediaType.APPLICATION_JSON)
    public String commonAccount(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                @RequestBody SaveCommonAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        if (CollectionUtils.isNotEmpty(param.getIncludes())) {
            return new ResponseResult<SaveCommonAccountParam, String>(user).run(getService(user)::commonAccount, param);
        } else {
            AccountParam reqParam = new AccountParam();
            reqParam.setBillMonth(param.getBillMonth());
            reqParam.setFlag(false);
            reqParam.setPaymentOrganization(param.getPaymentOrganization());
            return new ResponseResult<AccountParam, String>(user).run(getService(user)::save, reqParam);
        }
    }

    /**
     * 正常缴纳页 删除社保核算人员
     * @param request
     * @param response
     * @param param
     * @return
     */
    @POST
    @Path("/deleteSocialAcctEmp")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteSocialAcctEmp(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                @RequestBody SaveCommonAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SaveCommonAccountParam, String>(user).run(getService(user)::deleteSocialAcctEmp, param);
    }

    /**
     * 正常缴纳页 添加社保核算人员
     * @param request
     * @param response
     * @param param
     * @return
     */
    @POST
    @Path("/addSocialAcctEmp")
    @Produces(MediaType.APPLICATION_JSON)
    public String addSocialAcctEmp(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                      @RequestBody SaveCommonAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SaveCommonAccountParam, String>(user).run(getService(user)::addSocialAcctEmp, param);
    }


    /**
     * 删除月份表单
     *
     * @param request
     * @param response
     * @param param
     * @return
     */
    @POST
    @Path("/delete")
    @Produces(MediaType.APPLICATION_JSON)
    public String delete(@Context HttpServletRequest request, @Context HttpServletResponse response,
                         @RequestBody AccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AccountParam, String>(user).run(getService(user)::delete, param);
    }



    @GET
    @Path("/commonForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String queryCommonForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult< Map<String, Object>,  Map<String, Object>>(user).run(getService(user)::getCommonForm, ParamUtil.request2Map(request));
    }

    @POST
    @Path("/common/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String save(@Context HttpServletRequest request, @Context HttpServletResponse response,
                       @RequestBody SaveCommonAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SaveCommonAccountParam, String>(user).run(getService(user)::saveCommonAccount, param);
    }


    @GET
    @Path("/querySupplementaryForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String querySupplementaryForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult< Map<String, Object>,  Map<String, Object>>(user).run(getService(user)::getSupplementaryForm, ParamUtil.request2Map(request));
    }


    @POST
    @Path("/supplementary/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveSummplementaryAccount(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                            @RequestBody SaveSupplementaryAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SaveSupplementaryAccountParam, String>(user).run(getService(user)::saveSupplementaryAccount, param);
    }


    @POST
    @Path("/common/delete")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteCommon(@Context HttpServletRequest request, @Context HttpServletResponse response,
                               @RequestBody SaveCommonAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SaveCommonAccountParam, String>(user).run(getService(user)::deleteCommonAccount, param);
    }


    @POST
    @Path("/supplementary/delete")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteSummplementaryAccount(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                              @RequestBody SaveCommonAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SaveCommonAccountParam, String>(user).run(getService(user)::deleteSupplementaryAccount, param);
    }


    @POST
    @Path("/file")
    @Produces(MediaType.APPLICATION_JSON)
    public String file(@Context HttpServletRequest request, @Context HttpServletResponse response,
                       @RequestBody AccountParam accountParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AccountParam, String>(user).run(getService(user)::file, accountParam);
    }

    @POST
    @Path("/changeList")
    @Produces(MediaType.APPLICATION_JSON)
    public String changeList(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                        @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::changeList, insuranceAccountDetailParam);
    }



    @POST
    @Path("/overView")
    @Produces(MediaType.APPLICATION_JSON)
    public String overView(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                  @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, PageInfo<InsuranceAccountViewListDTO>>(user).run(getService(user)::overView, insuranceAccountDetailParam);
    }

    @GET
    @Path("/tabList")
    @Produces(MediaType.APPLICATION_JSON)
    public String tabList(@Context HttpServletRequest request, @Context HttpServletResponse response,
                              @QueryParam("billMonth") String billMonth,@QueryParam("paymentOrganization") Long paymentOrganization) {
        User user = HrmUserVarify.getUser(request, response);
        AccountParam build = AccountParam.builder().billMonth(billMonth).paymentOrganization(paymentOrganization).build();
        return new ResponseResult<AccountParam, InsuranceAccountTabDTO>(user).run(getService(user)::tabList, build);
    }

    @POST
    @Path("/inspectList")
    @Produces(MediaType.APPLICATION_JSON)
    public String getInspectTable(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                  @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::getInspectTable, insuranceAccountDetailParam);
    }



    @POST
    @Path("/inspectAccount")
    @Produces(MediaType.APPLICATION_JSON)
    public String accountInspect(@Context HttpServletRequest request, @Context HttpServletResponse response,
                         @RequestBody InspectAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InspectAccountParam, String>(user).run(getService(user)::accountInspect, param);
    }


    @POST
    @Path("/ignore")
    @Produces(MediaType.APPLICATION_JSON)
    public String ignore(@Context HttpServletRequest request, @Context HttpServletResponse response,
                              @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getService(user)::ignore, ids);
    }


    @POST
    @Path("/unconfirmed")
    @Produces(MediaType.APPLICATION_JSON)
    public String unconfirmed(@Context HttpServletRequest request, @Context HttpServletResponse response,
                         @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getService(user)::unconfirmed, ids);
    }


    @GET
    @Path("/getDisplayFlag")
    @Produces(MediaType.APPLICATION_JSON)
    public String buttonCheck(@Context HttpServletRequest request, @Context HttpServletResponse response,
                              @QueryParam("billMonth") String billMonth) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<String, Map<String, Boolean>>(user).run(getService(user)::buttonCheck, billMonth);
    }

    @GET
    @Path("/getAdminTaxAgentList")
    @Produces(MediaType.APPLICATION_JSON)
    public String getAdminTaxAgentList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<String, Collection<TaxAgentPO>>(user).run(getService(user)::getAdminTaxAgentList);
    }

    /**
     * 社保福利台账重新核算
     * @param request
     * @param response
     * @param insuranceAccountDetailParam 台账id
     * @return
     */
    @POST
    @Path("/socialSecurityBenefitsRecalculate")
    @Produces(MediaType.APPLICATION_JSON)
    public String socialSecurityBenefitsRecalculate(@Context HttpServletRequest request, @Context HttpServletResponse response,@RequestBody InsuranceAccountBatchPO insuranceAccountDetailParam ){
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountBatchPO, String>(user).run(getService(user)::socialSecurityBenefitsRecalculate,insuranceAccountDetailParam);
    }

    /**
     * 社保福利（核算）项列表
     */
    @GET
    @Path("/getWelfareList")
    @Produces(MediaType.APPLICATION_JSON)
    public String getWelfareList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<String,List<InsuranceAcctDetailImportFieldDTO>>(user).run(getSalaryFormulaWrapper(user)::welfareList);
    }

    /**
     * 社保福利（核算）项列表缓存（正常缴纳、补缴）
     * @param request
     * @param response
     * @param param
     * @return
     */
    @POST
    @Path("/cacheWelfareList")
    @Produces(MediaType.APPLICATION_JSON)
    public String cacheWelfareList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAcctDetailImportTemplateParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<List<String>, Void>(user).run(getService(user)::cacheWelfareField, param.getWelfareNames());
    }

    /**
     * 社保福利（核算）项列表缓存（正常缴纳、补缴）
     * @param request
     * @param response
     * @param param
     * @return
     */
    @POST
    @Path("/cacheBalanceWelfareList")
    @Produces(MediaType.APPLICATION_JSON)
    public String cacheBalanceWelfareList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAcctDetailImportTemplateParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<List<String>, Void>(user).run(getService(user)::cacheBalanceWelfareField, param.getWelfareNames());
    }

//    /**
//     * 导出“福利核算导入”模板
//     */
//    @GET
//    @Path("/welfare/importtemplate/export")
//    @Produces(MediaType.APPLICATION_OCTET_STREAM)
//    public Response exportImportTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response) {
//        try {
//            InsuranceAcctDetailImportTemplateParam param = new InsuranceAcctDetailImportTemplateParam();
//
//            param.setPaymentOrganization(Long.valueOf(request.getParameter("paymentOrganization")));
//            param.setBillMonth(request.getParameter("billMonth"));
//            String welfareNames = request.getParameter("welfareNames");
//            if (StringUtils.isNotBlank(welfareNames)) {
//                param.setWelfareNames(Arrays.stream(welfareNames.split(",")).map(String::valueOf).collect(Collectors.toList()));
//            }
//
//            User user = HrmUserVarify.getUser(request, response);
//            XSSFWorkbook workbook = getService(user).exportImportTemplate(param);
//            String time = LocalDate.now().toString();
//            String fileName = "福利核算导入模板" + time;
//            try {
//                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
//            StreamingOutput output = outputStream -> {
//                workbook.write(outputStream);
//                outputStream.flush();
//            };
//            response.setContentType("application/octet-stream");
//            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
//        } catch (Exception e) {
//            log.error("福利核算导入模板导出异常", e);
//            throw e;
//        }
//
//    }

    /**
     * 导出“福利核算导入”模板
     */
    @POST
    @Path("/welfare/importtemplate/export")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportImportTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAcctDetailImportTemplateParam param) {
        try {
//            InsuranceAcctDetailImportTemplateParam param = new InsuranceAcctDetailImportTemplateParam();
//
//            param.setPaymentOrganization(Long.valueOf(request.getParameter("paymentOrganization")));
//            param.setBillMonth(request.getParameter("billMonth"));
//            String welfareNames = request.getParameter("welfareNames");
//            if (StringUtils.isNotBlank(welfareNames)) {
//                param.setWelfareNames(Arrays.stream(welfareNames.split(",")).map(String::valueOf).collect(Collectors.toList()));
//            }

            User user = HrmUserVarify.getUser(request, response);
            XSSFWorkbook workbook = getService(user).exportImportTemplate(param);
            String time = LocalDate.now().toString();
            String fileName = "福利核算导入模板" + time;
            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };
            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
        } catch (Exception e) {
            log.error("福利核算导入模板导出异常", e);
            throw e;
        }

    }

    /**
     * 将通过“福利核算导入”模板导入的数据更新到hrsa_bill_detail表中
     */
    @POST
    @Path("/welfare/importInsuranceAcctDetail")
    @Produces(MediaType.APPLICATION_JSON)
    public String importInsuranceAcctDetail(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAcctImportParam insuranceAcctImportParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAcctImportParam, Map<String, Object>>(user).run(getService(user)::importInsuranceAcctDetail, insuranceAcctImportParam);
    }

    /**
     * 预览“福利核算导入”模板导入的数据
     */
    @POST
    @Path("/welfare/preview")
    @Produces(MediaType.APPLICATION_JSON)
    public String preview(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAcctImportParam insuranceAcctImportParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAcctImportParam, Map<String, Object>>(user).run(getService(user)::preview, insuranceAcctImportParam);
    }

//    /**
//     * 导出“福利核算-补缴导入”模板
//     */
//    @GET
//    @Path("/welfare/supplyimporttemplate/export")
//    @Produces(MediaType.APPLICATION_OCTET_STREAM)
//    public Response exportSupplyImportTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response) {
//        try {
//            InsuranceAcctDetailImportTemplateParam param = new InsuranceAcctDetailImportTemplateParam();
//
//            String welfareNames = request.getParameter("welfareNames");
//            String billMonth = request.getParameter("billMonth");
//            Long paymentOrganization = Long.valueOf(request.getParameter("paymentOrganization"));
//            if (StringUtils.isNotBlank(welfareNames)) {
//                param.setWelfareNames(Arrays.stream(welfareNames.split(",")).map(String::valueOf).collect(Collectors.toList()));
//            }
//            if (StringUtils.isNotBlank(billMonth)) {
//                param.setBillMonth(billMonth);
//            }
//            if (paymentOrganization > 0) {
//                param.setPaymentOrganization(paymentOrganization);
//            }
//
//            User user = HrmUserVarify.getUser(request, response);
//            XSSFWorkbook workbook = getService(user).exportSupplyImportTemplate(param);
//            String time = LocalDate.now().toString();
//            String fileName = "福利核算-补缴导入模板" + time;
//            try {
//                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
//            StreamingOutput output = outputStream -> {
//                workbook.write(outputStream);
//                outputStream.flush();
//            };
//            response.setContentType("application/octet-stream");
//            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
//        } catch (Exception e) {
//            log.error("福利核算-补缴导入模板导出异常", e);
//            throw e;
//        }
//
//    }

    /**
     * 导出“福利核算-补缴导入”模板
     */
    @POST
    @Path("/welfare/supplyimporttemplate/export")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportSupplyImportTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAcctDetailImportTemplateParam param) {
        try {
//            InsuranceAcctDetailImportTemplateParam param = new InsuranceAcctDetailImportTemplateParam();
//
//            String welfareNames = request.getParameter("welfareNames");
//            String billMonth = request.getParameter("billMonth");
//            Long paymentOrganization = Long.valueOf(request.getParameter("paymentOrganization"));
//            if (StringUtils.isNotBlank(welfareNames)) {
//                param.setWelfareNames(Arrays.stream(welfareNames.split(",")).map(String::valueOf).collect(Collectors.toList()));
//            }
//            if (StringUtils.isNotBlank(billMonth)) {
//                param.setBillMonth(billMonth);
//            }
//            if (paymentOrganization > 0) {
//                param.setPaymentOrganization(paymentOrganization);
//            }

            User user = HrmUserVarify.getUser(request, response);
            XSSFWorkbook workbook = getService(user).exportSupplyImportTemplate(param);
            String time = LocalDate.now().toString();
            String fileName = "福利核算-补缴导入模板" + time;
            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };
            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
        } catch (Exception e) {
            log.error("福利核算-补缴导入模板导出异常", e);
            throw e;
        }

    }
        // **********************************线下对比 start*********************************/
    /**
     * 导出“福利核算导入”模板
     */
    @GET
    @Path("/comparisonwelfare/importtemplate/export")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportComparisonWelfareTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            InsuranceAccountDetailParam param = new InsuranceAccountDetailParam();

            String billMonth = request.getParameter("billMonth");
            if (StringUtils.isNotBlank(billMonth)) {
                param.setBillMonth(billMonth);
            }
            String paymentOrganization = request.getParameter("paymentOrganization");
            if (StringUtils.isNotBlank(paymentOrganization)) {
                param.setPaymentOrganization(paymentOrganization);
            }

            String paymentStatus = request.getParameter("paymentStatus");
            if (StringUtils.isNotBlank(paymentStatus)) {
                param.setPaymentStatus(Integer.valueOf(paymentStatus));
            }

            User user = HrmUserVarify.getUser(request, response);
            XSSFWorkbook workbook = getService(user).exportComparisonWelfareTemplate(param);
            String time = LocalDate.now().toString();
            String fileName = "福利核算-线下对比导入模板" + time;
            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };
            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
        } catch (Exception e) {
            log.error("福利核算-线下对比导入模板导出异常", e);
            throw e;
        }

    }

    /**
     * 将通过“福利核算-线下对比导入”模板导入的数据更新到hrsa_excel_bill_detail表中
     */
    @POST
    @Path("/comparisonwelfare/importExcelInsuranceDetail")
    @Produces(MediaType.APPLICATION_JSON)
    public String importExcelInsuranceDetail(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody ExcelInsuranceImportParam excelInsuranceImportParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<ExcelInsuranceImportParam, Map<String, Object>>(user).run(getService(user)::importExcelInsuranceDetail, excelInsuranceImportParam);
    }


    //福利核算-线上线下对比结果列表
    @POST
    @Path("/comparisonwelfare/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String listComparisonResult(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceComparisonResultQueryParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceComparisonResultQueryParam, PageInfo<Map<String, Object>>>(user).run(getSIAComparisonResultWrapper(user)::listPage, param);
    }

    //导出福利核算-线上线下对比结果
    @GET
    @Path("/comparisonresult/export")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportComparisonResult(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            InsuranceComparisonResultQueryParam param = new InsuranceComparisonResultQueryParam();

            param.setPaymentStatus(Integer.valueOf(request.getParameter("paymentStatus")));
            param.setBillMonth(request.getParameter("billMonth"));
            param.setPaymentOrganization(request.getParameter("paymentOrganization"));
            String onlyDiffEmployee = request.getParameter("onlyDiffEmployee");
            if (StringUtils.isNotBlank(onlyDiffEmployee)) {
                param.setOnlyDiffEmployee(Boolean.parseBoolean(onlyDiffEmployee));
            }
            String userName = request.getParameter("userName");
            if (StringUtils.isNotBlank(userName)) {
                param.setUserName(userName);
            }

            User user = HrmUserVarify.getUser(request, response);
            XSSFWorkbook workbook = getSIAComparisonResultWrapper(user).exportComparisonResult(param);
            String time = LocalDate.now().toString();
            String fileName = "福利核算-线下对比结果" + time;
            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };
            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
        } catch (Exception e) {
            log.error("福利核算-线下对比结果导出异常", e);
            throw e;
        }
    }

    // **********************************线下对比 end*********************************/

    // **********************************退差 start*********************************/
    /**
     * 保存退差（新增）
     */
    @POST
    @Path("/saveRecession")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveRecession(@Context HttpServletRequest request, @Context HttpServletResponse response,
                       @RequestBody RecessionParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<RecessionParam, String>(user).run(getSIAccountWrapper(user)::saveRecession, param);
    }

    /**
     * 删除退差
     */
    @POST
    @Path("/delRecession")
    @Produces(MediaType.APPLICATION_JSON)
    public String delRecession(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getSIAccountWrapper(user)::delRecession, ids);
    }

    /**
     * 获取退差列表
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/recession/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String listRecessionPage(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                        @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listRecessionPage, insuranceAccountDetailParam);
    }


    /**
     * 获取退差列表合计列
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/recession/list/sum")
    @Produces(MediaType.APPLICATION_JSON)
    public String listRecessionSum(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                    @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listRecessionSum, insuranceAccountDetailParam);
    }

    /**
     * 通过id获取InsuranceAccountDetailPO中的社保、公积金、其他福利个人和公司缴纳数据
     * @param request
     * @param response
     * @param id
     * @return
     */
    @GET
    @Path("/getPaymentById")
    @Produces(MediaType.APPLICATION_JSON)
    public String getPaymentById(@Context HttpServletRequest request, @Context HttpServletResponse response,
                              @QueryParam("id") Long id) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, Map<String, Object>>(user).run(getService(user)::getPaymentById, id);
    }

    /**
     * 编辑InsuranceAccountDetailPO中的社保、公积金、其他福利个人和公司缴纳数据
     */
    @POST
    @Path("/editAccount")
    @Produces(MediaType.APPLICATION_JSON)
    public String editAccount(@Context HttpServletRequest request, @Context HttpServletResponse response,
                       @RequestBody EditAccountDetailParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<EditAccountDetailParam, String>(user).run(getService(user)::editAccount, param);
    }

    /**
     * 获取当前登录人所控制的人员范围
     */
    @POST
    @Path("/getEmployeeListByTaxAgent")
    @Produces(MediaType.APPLICATION_JSON)
    public String getEmployeeListByTaxAgent(@Context HttpServletRequest request, @Context HttpServletResponse response,
                              @RequestBody HrmQueryParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<HrmQueryParam, PageInfo<HrmInfoDTO>>(user).run(getSIAccountWrapper(user)::getEmployeeListByTaxAgent, param);
    }

    // **********************************退差 end*********************************/

    // **********************************调差 start*********************************/
    /**
     * 获取当前登录人所控制的人员范围
     */
    @POST
    @Path("/getEmployeeListToCompensation")
    @Produces(MediaType.APPLICATION_JSON)
    public String getEmployeeListToCompensation(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                            @RequestBody HrmQueryParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<HrmQueryParam, List<HrmInfoDTO>>(user).run(getSIAccountWrapper(user)::getEmployeeListToCompensation, param);
    }

    /**
     * 通过id获取InsuranceAccountDetailPO中的社保福利项
     */
    @GET
    @Path("/compensationCategoryType")
    @Produces(MediaType.APPLICATION_JSON)
    public String compensationCategoryType(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                 @QueryParam("id") Long id) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, List<Map<String, String>>>(user).run(getSIAccountWrapper(user)::compensationCategoryType, id);
    }

    /**
     * 获取当前调差福利类型-公司方支出总计
     */
    @POST
    @Path("/compensationComTotal")
    @Produces(MediaType.APPLICATION_JSON)
    public String compensationComTotal(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                @RequestBody List<CompensationParam> paramList) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<List<CompensationParam>, List<Map<String, String>>>(user).run(getSIAccountWrapper(user)::compensationComTotal, paramList);
    }

    /**
     * 社保调差保存
     */
    @POST
    @Path("/compensationSave")
    @Produces(MediaType.APPLICATION_JSON)
    public String compensationSave(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                       @RequestBody List<InsuranceCompensationDTO> param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<List<InsuranceCompensationDTO>, Map<String, Object>>(user).run(getSIAccountWrapper(user)::compensationSave, param);
    }

    /**
     * 社保调差默认配置保存
     */
    @POST
    @Path("/compensationConfigSave")
    @Produces(MediaType.APPLICATION_JSON)
    public String compensationConfigSave(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                   @RequestBody List<InsuranceCompensationDTO> param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<List<InsuranceCompensationDTO>, String>(user).run(getSIAccountWrapper(user)::compensationConfigSave, param);
    }

    /**
     * 社保调差撤回
     */
    @POST
    @Path("/compensationBack")
    @Produces(MediaType.APPLICATION_JSON)
    public String compensationBack(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                         @RequestBody InsuranceCompensationDTO param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceCompensationDTO, String>(user).run(getSIAccountWrapper(user)::compensationBack, param);
    }

    /**
     * 社保调差列表
     */
    @POST
    @Path("/compensationList")
    @Produces(MediaType.APPLICATION_JSON)
    public String compensationList(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                   @RequestBody InsuranceCompensationDTO param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceCompensationDTO, Map<String, Object>>(user).run(getSIAccountWrapper(user)::compensationList, param);
    }

    // **********************************调差 end*********************************/

    // **********************************补差 start*********************************/
    /**
     * 福利台账-补差福利项列表
     */
    @GET
    @Path("/getBalanceWelfareList")
    @Produces(MediaType.APPLICATION_JSON)
    public String getBalanceWelfareList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<String,List<InsuranceAcctDetailImportFieldDTO>>(user).run(getSalaryFormulaWrapper(user)::balanceWelfareList);
    }

//    /**
//     * 导出“福利核算-补差导入”模板
//     */
//    @GET
//    @Path("/welfare/balanceimporttemplate/export")
//    @Produces(MediaType.APPLICATION_OCTET_STREAM)
//    public Response exportBalanceImportTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response) {
//        try {
//            InsuranceAcctDetailImportTemplateParam param = new InsuranceAcctDetailImportTemplateParam();
//
//            param.setPaymentOrganization(Long.valueOf(request.getParameter("paymentOrganization")));
//            param.setBillMonth(request.getParameter("billMonth"));
//            String welfareNames = request.getParameter("welfareNames");
//            if (StringUtils.isNotBlank(welfareNames)) {
//                param.setWelfareNames(Arrays.stream(welfareNames.split(",")).map(String::valueOf).collect(Collectors.toList()));
//            }
//
//            User user = HrmUserVarify.getUser(request, response);
//            XSSFWorkbook workbook = getService(user).exportBalanceImportTemplate(param);
//            String time = LocalDate.now().toString();
//            String fileName = "福利台账-补差导入模板" + time;
//            try {
//                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
//            StreamingOutput output = outputStream -> {
//                workbook.write(outputStream);
//                outputStream.flush();
//            };
//            response.setContentType("application/octet-stream");
//            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
//        } catch (Exception e) {
//            log.error("福利台账-补差导入模板导出异常", e);
//            throw e;
//        }
//
//    }

    /**
     * 导出“福利核算-补差导入”模板
     */
    @POST
    @Path("/welfare/balanceimporttemplate/export")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportBalanceImportTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAcctDetailImportTemplateParam param) {
        try {
//            InsuranceAcctDetailImportTemplateParam param = new InsuranceAcctDetailImportTemplateParam();
//
//            param.setPaymentOrganization(Long.valueOf(request.getParameter("paymentOrganization")));
//            param.setBillMonth(request.getParameter("billMonth"));
//            String welfareNames = request.getParameter("welfareNames");
//            if (StringUtils.isNotBlank(welfareNames)) {
//                param.setWelfareNames(Arrays.stream(welfareNames.split(",")).map(String::valueOf).collect(Collectors.toList()));
//            }

            User user = HrmUserVarify.getUser(request, response);
            XSSFWorkbook workbook = getService(user).exportBalanceImportTemplate(param);
            String time = LocalDate.now().toString();
            String fileName = "福利台账-补差导入模板" + time;
            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };
            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
        } catch (Exception e) {
            log.error("福利台账-补差导入模板导出异常", e);
            throw e;
        }

    }
    /**
     * 将通过“福利台账-补差导入”模板导入的数据更新到hrsa_bill_detail表中
     */
    @POST
    @Path("/welfare/importBalanceInsuranceDetail")
    @Produces(MediaType.APPLICATION_JSON)
    public String importBalanceInsuranceDetail(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody InsuranceAcctImportParam insuranceAcctImportParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAcctImportParam, Map<String, Object>>(user).run(getService(user)::importBalanceInsuranceDetail, insuranceAcctImportParam);
    }

    /**
     * 删除补差
     */
    @POST
    @Path("/delBalance")
    @Produces(MediaType.APPLICATION_JSON)
    public String delBalance(@Context HttpServletRequest request, @Context HttpServletResponse response,
                               @RequestBody InspectAccountParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InspectAccountParam, String>(user).run(getSIAccountWrapper(user)::delBalance, param);
    }

    /**
     * 获取补差列表
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/balance/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String listBalancePage(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                        @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listBalancePage, insuranceAccountDetailParam);
    }

    /**
     * 获取补差列表合计列
     *
     * @param request
     * @param response
     * @param insuranceAccountDetailParam
     * @return
     */
    @POST
    @Path("/detail/balance/list/sum")
    @Produces(MediaType.APPLICATION_JSON)
    public String listBalanceSum(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                  @RequestBody InsuranceAccountDetailParam insuranceAccountDetailParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<InsuranceAccountDetailParam, Map<String, Object>>(user).run(getService(user)::listBalanceSum, insuranceAccountDetailParam);
    }
    // **********************************补差 end*********************************/

    /**
     * 取指定月份的福利缴纳基数作为补缴基数
     */
    @POST
    @Path("/detail/getSupplementPaymentForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSupplementPaymentForm(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                  @RequestBody SupplementAccountBaseParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SupplementAccountBaseParam, List<Map<String, String>>>(user).run(getSIAccountWrapper(user)::getSupplementPaymentForm, param);
    }

    /**
     * 获取待编辑的补缴费用相关福利项
     */
    @POST
    @Path("/detail/getPaymentGroup")
    @Produces(MediaType.APPLICATION_JSON)
    public String getPaymentGroup(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                           @RequestBody SupplementAccountBaseParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SupplementAccountBaseParam, List<Map<String, String>>>(user).run(getSIAccountWrapper(user)::getPaymentGroup, param);
    }

    /**
     * 获取待编辑的补差费用相关福利项
     */
    @POST
    @Path("/detail/getBalancePaymentGroup")
    @Produces(MediaType.APPLICATION_JSON)
    public String getBalancePaymentGroup(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                  @RequestBody BalanceAccountBaseParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<BalanceAccountBaseParam, List<Map<String, String>>>(user).run(getSIAccountWrapper(user)::getBalancePaymentGroup, param);
    }

    /**
     * 新增补差数据
     */
    @POST
    @Path("/detail/addNewBalance")
    @Produces(MediaType.APPLICATION_JSON)
    public String addNewBalance(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                         @RequestBody BalanceAccountBaseParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<BalanceAccountBaseParam, String>(user).run(getSIAccountWrapper(user)::addNewBalance, param);
    }
}
